/**
 * Copyright (C) 2021 - 2031 O-Cubes Co., Ltd.
 */

/****************************************************************
 *  @file    pcl.h
 *  @brief   PCL header file
 *  @version v1.0
 *  @date    03. Apr. 2023
 ****************************************************************/

#ifndef __PCL_H__
#define __PCL_H__

#include <stdint.h>
#include "bits.h"
#include "mem_map_table.h"

#ifdef __cplusplus
extern "C" {
#endif

/* PCL register base address*/
#define PCL_REG_BASE                    MEM_MAP_PCL_BASE_ADDR

/* IO Control Register address, Each pad corresponds to a register.
 * BIT[0] (OEN): Enable/Disable the transmitter;
 * BIT[1] (REN): Enable/Disable pull-up or pull-down;
 * BIT[4:2] (FUNC_SEL): Select IO function;
 * BIT[31:5]: RFU;
*/
#define PCL_SWPORT_IOCTL_ADDR(n)        (PCL_REG_BASE + n*4)

/* PCL SWPORT IOCTL Register bit fileds */
#define PCL_SWPORT_IOCTL_OEN            BIT(0) //0-enable the transmitter
#define PCL_SWPORT_IOCTL_REN            BIT(1) //1-disable pull-up or pull-down
#define PCL_SWPORT_IOCTL_FUN_SEL(n)     (n << 2)

/* SPI Three/Four Mode Select Register address
 * BIT[0] (TF_SPI0_SEL): 0 means four wire mdoe, 1 means three wire mode;
 * BIT[1] (TF_SPI1_SEL): 0 means four wire mdoe, 1 means three wire mode;
 * BIT[2] (TF_SPI2_SEL): 0 means dual SPI and qual SPI mode, 1 means standard SPI mode;
 * BIT[31:3]: RFU;
 */
#define PCL_TFS_CTL_ADDR                (PCL_REG_BASE + 0x120)

/* PCL TFS CTL Register bit fileds */
#define PCL_TFS_CTL_SPI0_SEL            BIT(0) //0-Four wire mode 1-Three wire mode
#define PCL_TFS_CTL_SPI1_2_SEL          BIT(1) //0-Four wire mdoe 1-Three wire mode
#define PCL_TFS_CTL_SPI3_SEL            BIT(2) //0-Dual SPI and Quad SPI mode 1-Standard SPI mode

/* PCL boot mode register address*/
#define PCL_BOOT_VAL_ADDR               (PCL_TFS_CTL_ADDR + 0x4)
/* PCL BOOT VAL Register bit fileds */
#define PCL_BOOT_VAL                    BIT(0) //0-BOOT_MOD0(FLASH BOOT)/1-BOOT_MOD1(UART UPGRADE)

/* PCL func value register address*/
#define PCL_FUNC_VAL_ADDR               (PCL_TFS_CTL_ADDR + 0x8)
/* PCL func value Register bit fileds */
#define PCL_FUNC0                       BIT(0)
#define PCL_FUNC1                       BIT(1)

/* PCL SYS JTAG register address*/
#define PCL_JTAG_CTL_ADDR               (PCL_TFS_CTL_ADDR + 0xC)
/* PCL SYS JTAG Register bit fileds */
#define PCL_JTAG_APB_SEL                BIT(0) //BIT[0:5]

/* APB switch enable signal in CPU_JTAG mdoe */
#define PCL_VLD                         (PCL_TFS_CTL_ADDR + 0x10)


typedef enum {
	PCL_FLASH_BOOT,
	PCL_ISP_PROGRAM,
} pcl_boot_mod;

typedef enum {
	PCL_SPI_DEV_ID0,
	PCL_SPI_DEV_ID1,
	PCL_SPI_DEV_ID2,
	PCL_SPI_DEV_ID3,
} pcl_spi_dev_id;

typedef enum {
	PCL_SPI_TF_QUAD,
	PCL_SPI_TF_STD,
} pcl_spi_tf;

typedef enum {
	PCL_SPI_FOUR_WIRE_MODE,
	PCL_SPI_THREE_WIRE_MODE,
} pcl_spi_wire_mode;

typedef enum {
	PCL_SELECT_FUNC1,
	PCL_SELECT_FUNC2,
	PCL_SELECT_FUNC3,
	PCL_SELECT_FUNC4,
	PCL_SELECT_FUNC5,
	PCL_SELECT_FUNC6,
	PCL_SELECT_MAX = 7,
} pcl_func_sel;

typedef enum {
	PCL_PDPU_CFG_ENABLE,
	PCL_PDPU_CFG_DISABLE,
} pcl_pd_pu_cfg;

typedef enum {
	PCL_PIN_OUTPUT_ENABLE,
	PCL_PIN_OUTPUT_DISABLE,
} pcl_pin_output_cfg;

typedef enum {
	PAD_ID_HRESET_N = 0,
	PAD_ID_BOOT_MOD,
	PAD_ID_FUNC_MOD0,
	PAD_ID_FUNC_MOD1,
	PAD_ID_SPI3_CLK,
	PAD_ID_SPI3_CSN = 5,
	PAD_ID_SPI3_IO0,
	PAD_ID_SPI3_IO1,
	PAD_ID_SPI3_IO2,
	PAD_ID_SPI3_IO3,
	PAD_ID_PWM_0 = 10,
	PAD_ID_PWM_1,
	PAD_ID_GPIO00,
	PAD_ID_GPIO01,
	PAD_ID_GPIO02,
	PAD_ID_GPIO03 = 15,
	PAD_ID_GPIO04,
	PAD_ID_GPIO05,
	PAD_ID_GPIO06,
	PAD_ID_GPIO07,
	PAD_ID_GPIO08 = 20,
	PAD_ID_GPIO09,
	PAD_ID_GPIO10,
	PAD_ID_GPIO11,
	PAD_ID_GPIO12,
	PAD_ID_GPIO13 = 25,
	PAD_ID_GPIO14,
	PAD_ID_GPIO15,
	PAD_ID_GPIO16,
	PAD_ID_GPIO17,
	PAD_ID_GPIO18 = 30,
	PAD_ID_GPIO19,
	PAD_ID_GPIO20,
	PAD_ID_GPIO21,
	PAD_ID_GPIO22,
	PAD_ID_GPIO23 = 35,
	PAD_ID_REV_24M_CLK,
	PAD_ID_REV_24M_SEL,
	PAD_ID_REV_32K_CLK,
	PAD_ID_REV_32K_SEL,
	PAD_ID_SYS_JTAG_SEL = 40,
} pcl_pad_id;

typedef enum {
	//pad id 12 func select
	PAD012_FUNC_SEP_ST_DETECT0 = 0,
	PAD012_FUNC_GPIO00,
	PAD012_FUNC_I2C0_SCL,

	//pad id 13 func select
	PAD013_FUNC_SEP_ST_DETECT1 = 0,
	PAD013_FUNC_GPIO01,
	PAD013_FUNC_I2C0_SDA,

	//pad id 14 func select
	PAD014_FUNC_GPIO02 = 0,
	PAD014_SPI0_CSN,
	PAD014_FUNC_CF1,

	//pad id 15 func select
	PAD015_FUNC_GPIO03 = 0,
	PAD015_SPI0_CLK,
	PAD015_FUNC_CF2,

	//pad id 16 func select
	PAD016_FUNC_GPIO04 = 0,
	PAD016_SPI0_SDIO,
	PAD016_FUNC_CF3,

	//pad id 17 func select
	PAD017_FUNC_GPIO05 = 0,
	PAD017_SPI0_SDO,
	PAD017_FUNC_CF4,

	//pad id 18 func select
	PAD018_FUNC_UART0_TXD = 0,
	PAD018_FUNC_GPIO06,
	PAD018_FUNC_I2C1_SCL,

	//pad id 19 func select
	PAD019_FUNC_UART0_RXD = 0,
	PAD019_FUNC_GPIO07,
	PAD019_FUNC_I2C1_SDA,

	//pad id 20 func select
	PAD020_FUNC_UART4_TXD = 0,
	PAD020_FUNC_GPIO08,
	PAD020_FUNC_UART1_TXD,
	PAD020_FUNC_SPI1_CSN,
	PAD020_FUNC_SPI2_CSN,

	//pad id 21 func select
	PAD021_FUNC_UART4_RXD = 0,
	PAD021_FUNC_GPIO09,
	PAD021_FUNC_UART1_RXD,
	PAD021_FUNC_SPI1_CLK,
	PAD021_FUNC_SPI2_CLK,

	//pad id 22 func select
	PAD022_FUNC_UART4_RTS = 0,
	PAD022_FUNC_GPIO10,
	PAD022_FUNC_UART3_TXD,
	PAD022_FUNC_SPI1_SDIO,
	PAD022_FUNC_SPI2_SDIO,

	//pad id 23 func select
	PAD023_FUNC_UART4_CTS = 0,
	PAD023_FUNC_GPIO11,
	PAD023_FUNC_UART3_RXD,
	PAD023_FUNC_SPI1_SDO,
	PAD023_FUNC_SPI2_SDO,

	//pad id 24 func select
	PAD024_FUNC_UART2_TXD = 0,
	PAD024_FUNC_GPIO12,

	//pad id 25 func select
	PAD025_FUNC_UART2_RXD = 0,
	PAD025_FUNC_GPIO13,

	//pad id 26 func select
	PAD026_FUNC_UART2_CON = 0,
	PAD026_FUNC_GPIO14,

	//pad id 27 func select
	PAD027_FUNC_OBS_CLK = 0,
	PAD027_FUNC_GPIO15,
	PAD027_FUNC_SPI0_CSN,
	PAD027_FUNC_UART1_TXD,

	//pad id 28 func select
	PAD028_FUNC_GPIO16 = 0,
	PAD028_FUNC_SPI0_CLK = 2,
	PAD028_FUNC_UART1_RXD,

	//pad id 29 func select
	PAD029_FUNC_E_RELAY_ST = 0,
	PAD029_FUNC_GPIO17,
	PAD029_FUNC_SPI0_SDIO,

	//pad id 30 func select
	PAD030_FUNC_PWM_FAULT = 0,
	PAD030_FUNC_GPIO18,
	PAD030_FUNC_SPI0_SDO,

	//pad id 31 func select
	PAD031_FUNC_SYS_JTAG_TRST = 0,
	PAD031_FUNC_GPIO19,
	PAD031_FUNC_CF1,
	PAD031_FUNC_SPI1_CSN,
	PAD031_FUNC_SPI2_CSN,
	PAD031_FUNC_CPU_JTAG_TRST,

	//pad id 32 func select
	PAD032_FUNC_SYS_JTAG_TCK = 0,
	PAD032_FUNC_GPIO20,
	PAD032_FUNC_CF2,
	PAD032_FUNC_SPI1_CLK,
	PAD032_FUNC_SPI2_CLK,
	PAD032_FUNC_CPU_JTAG_TCK,

	//pad id 33 func select
	PAD033_FUNC_SYS_JTAG_TMS = 0,
	PAD033_FUNC_GPIO21,
	PAD033_FUNC_CF3,
	PAD033_FUNC_SPI1_SDIO,
	PAD033_FUNC_SPI2_SDIO,
	PAD033_FUNC_CPU_JTAG_TMS,

	//pad id 34 func select
	PAD034_FUNC_SYS_JTAG_TDI = 0,
	PAD034_FUNC_GPIO22,
	PAD034_FUNC_CF4,
	PAD034_FUNC_SPI1_SDO,
	PAD034_FUNC_SPI2_SDO,
	PAD034_FUNC_CPU_JTAG_TDI,

	//pad id 35 func select
	PAD035_FUNC_SYS_JTAG_TDO = 0,
	PAD035_FUNC_GPIO23,
	PAD035_FUNC_CPU_JTAG_TDO,
} pad_func_select_list;

void pcl_set_spi3_tf(pcl_spi_tf tf);
void pcl_set_spi_wire_mode(pcl_spi_dev_id spi_id, pcl_spi_wire_mode mode);
void pcl_pd_pu_set(uint32_t pad_id, pcl_pd_pu_cfg cfg);
void pcl_pin_output_set(uint32_t pad_id, pcl_pin_output_cfg cfg);
void pcl_func_select(uint32_t pad_id, pcl_func_sel func);
pcl_func_sel pcl_func_get(uint32_t pad_id);
void pcl_init(void);
pcl_boot_mod pcl_get_bootmod(void);

#ifdef __cplusplus
}
#endif

#endif /* __PCL_H__ */
